home *** CD-ROM | disk | FTP | other *** search
- ; EX12_3.asm
- ;
- ; Ex12_3.asm
- ;
- ; This program demonstrates different parameter passing methods.
- ; It corresponds to the following (pseudo) Pascal code:
- ;
- ;
- ; program main;
- ; var i:integer;
- ; a:array[0..255] of integer;
- ; b:array[0..255] of unsigned;
- ;
- ; function LTint(int1, int2:integer):boolean;
- ; begin
- ; LTint := int1 < int2;
- ; end;
- ;
- ; procedure SwapInt(var int1, int2:integer);
- ; var temp:integer;
- ; begin
- ; temp := int1;
- ; int1 := int2;
- ; int2 := temp;
- ; end;
- ;
- ; function LTunsigned(uns1, uns2:unsigned):boolean;
- ; begin
- ; LTunsigned := uns1 < uns2;
- ; end;
- ;
- ; procedure SwapUnsigned(uns1, uns2:unsigned);
- ; var temp:unsigned;
- ; begin
- ; temp := uns1;
- ; uns1 := uns2;
- ; uns2 := temp;
- ; end;
- ;
- ; (* The following is a simple Bubble sort that will sort arrays containing *)
- ; (* arbitrary data types. *)
- ;
- ; procedure sort(data:array; elements:integer; function LT:boolean; procedure swap);
- ; var i,j:integer;
- ; begin
- ;
- ; for i := 0 to elements-1 do
- ; for j := i+1 to elements do
- ; if (LT(data[j], data[i])) then swap(data[i], data[j]);
- ; end;
- ;
- ;
- ; begin
- ;
- ; for i := 0 to 255 do A[i] := 128-i;
- ; for i := 0 to 255 do B[i] := 33000-i;
- ; sort(A, 256, LTint, SwapInt);
- ; sort(B, 256, LTunsigned, SwapUnsigned);
- ;
- ; for i := 0 to 255 do
- ; begin
- ; if (i mod 8) = 0 then writeln;
- ; write(A[i]:7);
- ; end;
- ;
- ; for i := 0 to 255 do
- ; begin
- ; if (i mod 8) = 0 then writeln;
- ; write(B[i]:7);
- ; end;
- ;
- ; end;
-
- .xlist
- include stdlib.a
- includelib stdlib.lib
- .list
-
- .386
- option segment:use16
-
- wp textequ <word ptr>
-
-
- dseg segment para public 'data'
- A word 256 dup (?)
- B word 256 dup (?)
- dseg ends
-
-
-
- cseg segment para public 'code'
- assume cs:cseg, ds:dseg, ss:sseg
-
-
- ; function LTint(int1, int2:integer):boolean;
- ; begin
- ; LTint := int1 < int2;
- ; end;
- ;
- ; LTint's activation record looks like this:
- ;
- ; |----------------|
- ; | int1 |
- ; |----------------|
- ; | int2 |
- ; |----------------|
- ; | return address |
- ; |----------------|
- ; | old BP |<- SP, BP
- ; |----------------|
-
- int1 textequ <word ptr [bp+6]>
- int2 textequ <word ptr [bp+4]>
-
- LTint proc near
- push bp
- mov bp, sp
-
- mov ax, int1 ;Compare the two parameters
- cmp ax, int2 ; and return true if int1<int2.
- setl al ;Signed comparison here.
- mov ah, 0 ;Be sure to clear H.O. byte.
-
- pop bp
- ret 4
- LTint endp
-
-
- ; Swap's activation record looks like this:
- ;
- ; |----------------|
- ; | Address |
- ; |--- of ---|
- ; | int1 |
- ; |----------------|
- ; | Address |
- ; |--- of ---|
- ; | int2 |
- ; |----------------|
- ; | return address |
- ; |----------------|
- ; | old BP |<- SP, BP
- ; |----------------|
- ;
- ; The temporary variable is kept in a register.
- ;
- ; Note that swapping integers or unsigned integers can be done
- ; with the same code since the operations are identical for
- ; either type.
- ;
- ; procedure SwapInt(var int1, int2:integer);
- ; var temp:integer;
- ; begin
- ; temp := int1;
- ; int1 := int2;
- ; int2 := temp;
- ; end;
- ;
- ; procedure SwapUnsigned(uns1, uns2:unsigned);
- ; var temp:unsigned;
- ; begin
- ; temp := uns1;
- ; uns1 := uns2;
- ; uns2 := temp;
- ; end;
- ;
-
- int1 textequ <dword ptr [bp+8]>
- int2 textequ <dword ptr [bp+4]>
-
- SwapInt proc near
- push bp
- mov bp, sp
- push es
- push bx
-
- les bx, int1 ;Get address of int1 variable.
- mov ax, es:[bx] ;Get int1's value.
- les bx, int2 ;Get address of int2 variable.
- xchg ax, es:[bx] ;Swap int1's value with int2's
-
- les bx, int1 ;Get the address of int1 and
- mov es:[bx], ax ; store int2's value there.
-
- pop bx
- pop es
- pop bp
- ret 8
- SwapInt endp
-
-
-
- ; LTunsigned's activation record looks like this:
- ;
- ; |----------------|
- ; | uns1 |
- ; |----------------|
- ; | uns2 |
- ; |----------------|
- ; | return address |
- ; |----------------|
- ; | old BP |<- SP, BP
- ; |----------------|
- ;
- ; function LTunsigned(uns1, uns2:unsigned):boolean;
- ; begin
- ; LTunsigned := uns1 < uns2;
- ; end;
-
- uns1 textequ <word ptr [bp+6]>
- uns2 textequ <word ptr [bp+4]>
-
- LTunsigned proc near
- push bp
- mov bp, sp
-
- mov ax, uns1 ;Compare uns1 with uns2 and
- cmp ax, uns2 ; return true if uns1<uns2.
- setb al ;Unsigned comparison.
- mov ah, 0 ;Return 16-bit boolean.
-
- pop bp
- ret 4
- LTunsigned endp
-
-
-
- ; Sort's activation record looks like this:
- ;
- ; |----------------|
- ; | Data's |
- ; |--- ---|
- ; | Address |
- ; |----------------|
- ; | Elements |
- ; |----------------|
- ; | LT's |
- ; |--- ---|
- ; | Address |
- ; |----------------|
- ; | Swap's |
- ; |--- ---|
- ; | Address |
- ; |----------------|
- ; | return address |
- ; |----------------|
- ; | old BP |<- SP, BP
- ; |----------------|
- ;
- ; procedure sort(data:array; elements:integer; function LT:boolean; procedure swap);
- ; var i,j:integer;
- ; begin
- ;
- ; for i := 0 to elements-1 do
- ; for j := i+1 to elements do
- ; if (LT(data[j], data[i])) then swap(data[i], data[j]);
- ; end;
-
-
- data textequ <dword ptr [bp+10]>
- elements textequ <word ptr [bp+8]>
- funcLT textequ <word ptr [bp+6]>
- procSwap textequ <word ptr [bp+4]>
-
- i textequ <word ptr [bp-2]>
- j textequ <word ptr [bp-4]>
-
- sort proc near
- push bp
- mov bp, sp
- sub sp, 4
- push es
- push bx
-
- mov i, 0
- ForILp: mov ax, i ;Compare with elements-1.
- inc ax ;Do this by incrementing I
- cmp ax, Elements ; and comparing with Elements.
- jae IDone
-
- mov j, ax ;Put i+1 into J.
- ForJLp: mov ax, j
- cmp ax, Elements
- jae JDone
-
- les bx, data ;Push the value of
- mov si, j ; data[j] onto the
- add si, si ; stack.
- push es:[bx+si]
-
- les bx, data ;Push the value of
- mov si, i ; data[i] onto the
- add si, si ; stack.
- push es:[bx+si]
-
- call FuncLT ;See if data[i] < data[j]
- cmp ax, 0 ;Test boolean result.
- je NextJ
-
- push wp data+2 ;Pass data[i] by reference.
- mov ax, i
- add ax, ax
- add ax, wp data
- push ax
-
- push wp data+2 ;Pass data[j] by reference.
- mov ax, j
- add ax, ax
- add ax, wp data
- push ax
-
- call ProcSwap
-
- NextJ: inc j
- jmp ForJLp
-
- JDone: inc i
- jmp ForILp
-
- IDone: pop bx
- pop es
- mov sp, bp
- pop bp
- ret 10
- sort endp
-
-
-
-
-
- ; Main's activation record looks like this:
- ;
- ; | return address |<- SP, BP
- ; |----------------|
- ;
- ; begin
- ;
- ; for i := 0 to 255 do A[i] := 128-i;
- ; for i := 0 to 255 do B[i] := 33000-i;
- ; sort(A, 256, LTint, SwapInt);
- ; sort(B, 256, LTunsigned, SwapUnsigned);
- ;
- ; for i := 0 to 255 do
- ; begin
- ; if (i mod 8) = 0 then writeln;
- ; write(A[i]:7);
- ; end;
- ;
- ; for i := 0 to 255 do
- ; begin
- ; if (i mod 8) = 0 then writeln;
- ; write(B[i]:7);
- ; end;
- ;
- ; end;
-
- Main proc
- mov ax, dseg ;Initialize the segment registers.
- mov ds, ax
- mov es, ax
-
- ; Note that the following code merges the two initialization for loops
- ; into a single loop.
-
- mov ax, 128
- mov bx, 0
- mov cx, 33000
- ForILp: mov A[bx], ax
- mov B[bx], cx
- add bx, 2
- dec ax
- dec cx
- cmp bx, 256*2
- jb ForILp
-
- push ds ;Seg address of A
- push offset A ;Offset of A
- push 256 ;# of elements in A
- push offset LTint ;Address of compare routine
- push offset SwapInt ;Address of swap routine
- call Sort
-
-
- push ds ;Seg address of B
- push offset B ;Offset of B
- push 256 ;# of elements in A
- push offset LTunsigned ;Address of compare routine
- push offset SwapInt ;Address of swap routine
- call Sort
-
- ; Print the values in A.
-
- mov bx, 0
- ForILp2: test bx, 0Fh ;See if (I mod 8) = 0
- jnz NotMod ; note: BX mod 16 = I mod 8.
- putcr
- NotMod: mov ax, A[bx]
- mov cx, 7
- putisize
- add bx, 2
- cmp bx, 256*2
- jb ForILp2
-
- ; Print the values in B.
-
- putcr
-
- mov bx, 0
- ForILp3: test bx, 0Fh ;See if (I mod 8) = 0
- jnz NotMod2 ; note: BX mod 16 = I mod 8.
- putcr
- NotMod2: mov ax, B[bx]
- mov cx, 7
- putusize
- add bx, 2
- cmp bx, 256*2
- jb ForILp3
-
- Quit: ExitPgm ;DOS macro to quit program.
- Main endp
-
-
-
- cseg ends
-
-
- sseg segment para stack 'stack'
- stk word 256 dup (0)
- sseg ends
-
- zzzzzzseg segment para public 'zzzzzz'
- LastBytes db 16 dup (?)
- zzzzzzseg ends
- end Main
-